#include <iostream>
#include <vector>
using namespace std;

struct SparseMatrix {
    int rows;
    int cols;
    vector<vector<int>> elements;
};

SparseMatrix createSparseMatrix(int rows, int cols, const vector<vector<int>>& matrix) {
    SparseMatrix sparseMatrix;
    sparseMatrix.rows = rows;
    sparseMatrix.cols = cols;

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (matrix[i][j] != 0) {
                sparseMatrix.elements.push_back({i, j, matrix[i][j]});
            }
        }
    }

    return sparseMatrix;
}

SparseMatrix addSparseMatrices(const SparseMatrix& matrix1, const SparseMatrix& matrix2) {
    if (matrix1.rows != matrix2.rows || matrix1.cols != matrix2.cols) {
        cout << "Error: Matrix dimensions do not match." << endl;
        exit(0);
    }

    SparseMatrix result;
    result.rows = matrix1.rows;
    result.cols = matrix1.cols;

    int index1 = 0;
    int index2 = 0;

    while (index1 < matrix1.elements.size() && index2 < matrix2.elements.size()) {
        int row1 = matrix1.elements[index1][0];
        int col1 = matrix1.elements[index1][1];
        int value1 = matrix1.elements[index1][2];

        int row2 = matrix2.elements[index2][0];
        int col2 = matrix2.elements[index2][1];
        int value2 = matrix2.elements[index2][2];

        if (row1 < row2 || (row1 == row2 && col1 < col2)) {
            result.elements.push_back({row1, col1, value1});
            index1++;
        } else if (row1 > row2 || (row1 == row2 && col1 > col2)) {
            result.elements.push_back({row2, col2, value2});
            index2++;
        } else {
            result.elements.push_back({row1, col1, value1 + value2});
            index1++;
            index2++;
        }
    }

    while (index1 < matrix1.elements.size()) {
        result.elements.push_back(matrix1.elements[index1]);
        index1++;
    }

    while (index2 < matrix2.elements.size()) {
        result.elements.push_back(matrix2.elements[index2]);
        index2++;
    }

    return result;
}

SparseMatrix multiplySparseMatrices(const SparseMatrix& matrix1, const SparseMatrix& matrix2) {
    if (matrix1.cols != matrix2.rows) {
        cout << "Error: Matrix dimensions do not match for multiplication." << endl;
        exit(0);
    }

    SparseMatrix result;
    result.rows = matrix1.rows;
    result.cols = matrix2.cols;

    vector<vector<int>> transposeMatrix;
    transposeMatrix.resize(matrix2.cols);

    for (int i = 0; i < matrix2.cols; i++) {
        transposeMatrix[i].resize(matrix2.rows);
    }

    for (int i = 0; i < matrix2.elements.size(); i++) {
        int row = matrix2.elements[i][0];
        int col = matrix2.elements[i][1];
        int value = matrix2.elements[i][2];
        transposeMatrix[col][row] = value;
    }

    for (int i = 0; i < matrix1.rows; i++) {
        for (int j = 0; j < matrix2.cols; j++) {
            int sum = 0;
            for (int k = 0; k < matrix1.cols; k++) {
                sum += (matrix1.elements[i * matrix1.cols + k][2] * transposeMatrix[j][k]);
            }
            if (sum != 0) {
                result.elements.push_back({i, j, sum});
            }
        }
    }

    return result;
}

void printSparseMatrix(const SparseMatrix& matrix) {
    cout << "Sparse Matrix [" << matrix.rows << "x" << matrix.cols << "]:" << endl;
    for (int i = 0; i < matrix.elements.size(); i++) {
        cout << matrix.elements[i][0] << " " << matrix.elements[i][1] << " " << matrix.elements[i][2] << endl;
    }
    cout << endl;
}

int main() {
    vector<vector<int>> matrix1 = {{0, 0, 3}, {1, 1, 5}, {2, 2, 4}};
    SparseMatrix sparseMatrix1 = createSparseMatrix(3, 3, matrix1);

    vector<vector<int>> matrix2 = {{0, 0, 9}, {0, 1, 2}, {2, 2, 8}};
    SparseMatrix sparseMatrix2 = createSparseMatrix(3, 3, matrix2);

    SparseMatrix sumMatrix = addSparseMatrices(sparseMatrix1, sparseMatrix2);
    cout << "Addition of sparse matrices:" << endl;
    printSparseMatrix(sumMatrix);

    SparseMatrix prodMatrix = multiplySparseMatrices(sparseMatrix1, sparseMatrix2);
    cout << "Multiplication of sparse matrices:" << endl;
    printSparseMatrix(prodMatrix);

    return 0;
}